package com.ymatou.payment.testcase;

import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.payment.serivce.CallbackCall;
import com.ymatou.paymentproxy.parameter.AcquireOrderBean;
import com.ymatou.paymentproxy.parameter.AliPayNotifyBean;
import com.ymatou.paymentproxy.parameter.AliPayWapCallBackBean;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.business.data.Sign;
import com.ymttest.business.service.PaymentProxyCallService;
import com.ymttest.database.model.PPBussinessOrder;
import com.ymttest.database.model.PPPayment;
import com.ymttest.database.sqlwapper.PaymentDefaultWapper;
import com.ymttest.utils.TestDataManager;

/**
 * 支付同步回调接口 FreeMaker Template自动生成代码 回调主要验证微信JSAPI APP 支付宝PC APP场景 验证签名 返回码 支付号
 * 金额 商户号 异常情况
 * 验证不同渠道PayRecharge,PostPay,Recharge,SellerMarginRecharge,SellerRecharge资金流水
 */
@TestSuite
public class Ts_Callback {
	private static AliPayNotifyBean alinotifyBean;
	private static CallbackCall callbackCall;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("支付同步回调接口");
	}

	@Before
	public void caseUp() {
		alinotifyBean = new AliPayNotifyBean();
		callbackCall = new CallbackCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(callbackCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_Callback_001() {
		Logger.start(true, "10支付宝PC支付同步回调成功");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("10");
			PaymentProxyCallService.acquireOrder(aqb);

			callbackCall = new CallbackCall("10");
			callbackCall.setRedirects(false);
			alinotifyBean = PaymentProxyCallService.initAliPayNotifyBean(aqb);
			String send = aliPayNotifyBeanToSend(alinotifyBean);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(302, callbackCall.getStatusCode(), "验证StatusCode重定向");
			Logger.comment("Location字段数据验证");
			List<String> list = callbackCall.getAllHeader();
			//获取Location uri
			String uri="";
			for (String string : list) {
				String key=string.split(":")[0];
				if(key.equals("location")){
					uri=string.substring(string.indexOf(":")+1);
				}
			}
			Logger.comment("Location uri:"+uri);
			//解析其参数
			String httpp=uri.substring(uri.indexOf("?")+1);
			Map m=FormatUtil.httpStringToMap(httpp);
			
			Logger.verifyEquals(Double.valueOf(aqb.getPayPrice()),Double.valueOf(m.get("PayPrice").toString()),"验证金额");
			Logger.verifyEquals(aqb.getCurrency(),m.get("Currency").toString(),"验证Currency");
			Logger.verifyEquals(aqb.getPayType(),m.get("PayType").toString(),"验证PayType");
			PPBussinessOrder ppb = new PaymentDefaultWapper().selectPPBussinessorderByOrderId(aqb.getOrderId()).get(0);
			String businessoid = ppb.getBussinessOrderId();
			PPPayment ppm = new PaymentDefaultWapper().selectPPPaymentByBussinessOrderId(businessoid).get(0);
			String trandno = ppm.getPaymentId();
			Logger.verifyEquals(trandno,m.get("PaymentId").toString(),"验证PaymentId");
			Logger.verifyEquals(alinotifyBean.getTrade_no(),m.get("InstPaymentId").toString(),"验证InstPaymentId");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_Callback_002() {
		Logger.start(false, "商户网站唯一订单号错误10支付宝PC支付同步回调失败");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("10");
			PaymentProxyCallService.acquireOrder(aqb);

			callbackCall = new CallbackCall("10");
			callbackCall.setRedirects(false);
			alinotifyBean = PaymentProxyCallService.initAliPayNotifyBean(aqb);
			alinotifyBean.setOut_trade_no("123");
			String send = aliPayNotifyBeanToSend(alinotifyBean);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(500, callbackCall.getStatusCode(), "验证StatusCode重定向");
//			Logger.verifyEquals("Houston, we have a problem.", callbackCall.getReturnData(), "验证returndata");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_Callback_003() {
		Logger.start(false, "不输入商户网站唯一订单号10支付宝PC支付同步回调失败");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("10");
			PaymentProxyCallService.acquireOrder(aqb);

			callbackCall = new CallbackCall("10");
			callbackCall.setRedirects(false);
			alinotifyBean = PaymentProxyCallService.initAliPayNotifyBean(aqb);
			alinotifyBean.setOut_trade_no(null);
			String send = aliPayNotifyBeanToSend(alinotifyBean);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(500, callbackCall.getStatusCode(), "验证StatusCode重定向");
//			Logger.verifyEquals("Houston, we have a problem.", callbackCall.getReturnData(), "验证returndata");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	@Ignore
	//callback 旧站点不验签
	public void Tc_Callback_004() {
		Logger.start(false, "回调签名错误10支付宝PC支付同步回调失败");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("10");
			PaymentProxyCallService.acquireOrder(aqb);
			callbackCall = new CallbackCall("10");
			callbackCall.setRedirects(false);
			alinotifyBean = PaymentProxyCallService.initAliPayNotifyBean(aqb);
			String src = FormatUtil.beanToHttpString(alinotifyBean, false);
			String sign = new Sign().signMd5(aqb, Sign.autoTestKey);
			alinotifyBean.setSign(sign+1);
			alinotifyBean.setSign_type("MD5");
			// 转换成最终发出的数据
			String send = FormatUtil.beanToHttpString(alinotifyBean, true);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(500, callbackCall.getStatusCode(), "验证StatusCode重定向");
			Logger.verifyEquals("Houston, we have a problem.", callbackCall.getReturnData(), "验证returndata");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	@Ignore
	//目前业务上是不支持支付宝APP同步回调的
	public void Tc_Callback_005() {
		Logger.start(true, "13支付宝APP支付同步回调成功");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("13");
			PaymentProxyCallService.acquireOrder(aqb);

			callbackCall = new CallbackCall("13");
			callbackCall.setRedirects(false);
			alinotifyBean = PaymentProxyCallService.initAliPayNotifyBean(aqb);
			String send = aliPayNotifyBeanToSend(alinotifyBean);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(302, callbackCall.getStatusCode(), "验证StatusCode重定向");
			Logger.comment("Location字段数据验证");
			List<String> list = callbackCall.getAllHeader();
			//获取Location uri
			String uri="";
			for (String string : list) {
				String key=string.split(":")[0];
				if(key.equals("location")){
					uri=string.substring(string.indexOf(":")+1);
				}
			}
			//解析其参数
			String httpp=uri.substring(uri.indexOf("?")+1);
			Map m=FormatUtil.httpStringToMap(httpp);
			
			Logger.verifyEquals(Double.valueOf(aqb.getPayPrice()),Double.valueOf(m.get("PayPrice").toString()),"验证金额");
			Logger.verifyEquals(aqb.getCurrency(),m.get("Currency").toString(),"验证Currency");
			Logger.verifyEquals(aqb.getPayType(),m.get("PayType").toString(),"验证PayType");
			PPBussinessOrder ppb = new PaymentDefaultWapper().selectPPBussinessorderByOrderId(aqb.getOrderId()).get(0);
			String businessoid = ppb.getBussinessOrderId();
			PPPayment ppm = new PaymentDefaultWapper().selectPPPaymentByBussinessOrderId(businessoid).get(0);
			String trandno = ppm.getPaymentId();
			Logger.verifyEquals(trandno,m.get("PaymentId").toString(),"验证PaymentId");
			Logger.verifyEquals(alinotifyBean.getTrade_no(),m.get("InstPaymentId").toString(),"验证InstPaymentId");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_Callback_006() {
		Logger.start(true, "11支付宝wap支付同步回调成功");
		try {
			AcquireOrderBean aqb = PaymentProxyCallService.initAcquireOrder("11");
			PaymentProxyCallService.acquireOrder(aqb);
			AliPayWapCallBackBean aliwapcb=PaymentProxyCallService.initAliPayCallBackBean(aqb);
			String src = FormatUtil.beanToHttpString(aliwapcb, false);
			String sign = new Sign().signMd5(aliwapcb, Sign.autoTestKey);
			aliwapcb.setSign(sign);
			aliwapcb.setSign_type("MD5");
			String send = FormatUtil.beanToHttpString(aliwapcb, true);
			
			callbackCall = new CallbackCall("11");
			callbackCall.setRedirects(false);
			callbackCall.setData(send);
			callbackCall.addHeader("Mock", "1");
			String mockid = TestDataManager.getRandomUUID().toString();
			callbackCall.addHeader("MockId", mockid);
			Logger.comment("添加Mock:" + mockid);
			callbackCall.callService();
			Logger.verifyEquals(302, callbackCall.getStatusCode(), "验证StatusCode重定向");
			Logger.comment("Location字段数据验证");
			List<String> list = callbackCall.getAllHeader();
			//获取Location uri
			String uri="";
			for (String string : list) {
				String key=string.split(":")[0];
				if(key.equals("location")){
					uri=string.substring(string.indexOf(":")+1);
				}
			}
			Logger.comment("Location uri:"+uri);
			//解析其参数
			String httpp=uri.substring(uri.indexOf("?")+1);
			Map m=FormatUtil.httpStringToMap(httpp);
			
			Logger.verifyEquals(Double.valueOf(aqb.getPayPrice()),Double.valueOf(m.get("PayPrice").toString()),"验证金额");
			Logger.verifyEquals(aqb.getCurrency(),m.get("Currency").toString(),"验证Currency");
			Logger.verifyEquals(aqb.getPayType(),m.get("PayType").toString(),"验证PayType");
			PPBussinessOrder ppb = new PaymentDefaultWapper().selectPPBussinessorderByOrderId(aqb.getOrderId()).get(0);
			String businessoid = ppb.getBussinessOrderId();
			PPPayment ppm = new PaymentDefaultWapper().selectPPPaymentByBussinessOrderId(businessoid).get(0);
			String trandno = ppm.getPaymentId();
			Logger.verifyEquals(trandno,m.get("PaymentId").toString(),"验证PaymentId");
			Logger.verifyEquals(aliwapcb.getTrade_no(),m.get("InstPaymentId").toString(),"验证InstPaymentId");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	/**
	 * AliPayNotifyBean加签并转换为SendString
	 * 
	 * @param alipaybean
	 * @return
	 * @throws Exception
	 */
	private String aliPayNotifyBeanToSend(AliPayNotifyBean alipaybean) throws Exception {
		Logger.comment("AliPayNotifyBean加签并转换为SendString");
		String send = null;
		if (alipaybean.getPayment_type().equals("13")) {
			// 排序加签名
			String src = FormatUtil.beanToHttpString(alipaybean, false);
			String sign = Sign.SignSHA1WithRSA(src);
			alipaybean.setSign(sign);
			alipaybean.setSign_type("RSA");
			// 转换成最终发出的数据
			send = FormatUtil.beanToHttpString(alipaybean, true);
		} else {
			String src = FormatUtil.beanToHttpString(alipaybean, false);
			String sign = new Sign().signMd5(alipaybean, Sign.autoTestKey);
			alipaybean.setSign(sign);
			alipaybean.setSign_type("MD5");
			send = FormatUtil.beanToHttpString(alipaybean, true);
		}
		return send;
	}

}